# 葵崽专属管理器
# 版本: 2.0.0
# 作者: 向日葵
# 功能: XRK-Yunzai机器人一键部署管理工具

# 要求管理员权限运行
#Requires -RunAsAdministrator

# 设置控制台编码为UTF-8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
chcp 65001 | Out-Null

# 加载必要的程序集
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

#region 全局变量定义
$global:basePath = ""
$global:yunzaiDir = ""
$global:workspacePath = ""
$global:projectPath = ""
$global:logPath = ""
$global:softwarePath = ""
$global:napCatPath = ""
$global:useGitHubProxy = $true
$global:selectedGitHubProxy = "https://gh-proxy.com/"
$global:skipPathDialog = $false
$global:gitBashPath = ""
$global:updateUrl = "https://gitcode.com/Xrkseek/XRK-Yunzai/releases/download/XRK-win/XRK-win.exe"
$global:downloadTimeout = 180
$global:appVersion = "2.0.0"

# GitHub代理服务器列表
$global:githubProxies = @(
    @{ Name = "gh-proxy.com"; Url = "https://gh-proxy.com/" },
    @{ Name = "ghp.ci"; Url = "https://ghp.ci/" },
    @{ Name = "ghproxy.net"; Url = "https://mirror.ghproxy.com/" },
    @{ Name = "github.moeyy.xyz"; Url = "https://github.moeyy.xyz/" }
)

# UI主题颜色配置
$global:colors = @{
    Primary = [System.Drawing.Color]::FromArgb(41, 128, 185)
    Success = [System.Drawing.Color]::FromArgb(39, 174, 96)
    Warning = [System.Drawing.Color]::FromArgb(243, 156, 18)
    Danger = [System.Drawing.Color]::FromArgb(231, 76, 60)
    Secondary = [System.Drawing.Color]::FromArgb(149, 165, 166)
    Dark = [System.Drawing.Color]::FromArgb(52, 73, 94)
    Light = [System.Drawing.Color]::FromArgb(236, 240, 241)
    White = [System.Drawing.Color]::White
    Purple = [System.Drawing.Color]::FromArgb(142, 68, 173)
}

# 窗口缩放相关变量
$global:scaleFactor = 1.0
$global:baseFont = New-Object System.Drawing.Font("Microsoft YaHei UI", 9)
#endregion

#region 配置文件管理
function Initialize-Config {
    $appDataPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::ApplicationData)
    $configDir = Join-Path $appDataPath "Yunzai-Manager"
    if (-not (Test-Path $configDir)) {
        New-Item -ItemType Directory -Path $configDir -Force | Out-Null
    }
    return Join-Path $configDir "config.json"
}

function Save-Config {
    $configPath = Initialize-Config
    $config = @{
        LastInstallPath = $global:basePath
        YunzaiDirName = if ($global:yunzaiDir) { Split-Path $global:yunzaiDir -Leaf } else { "" }
        UseGitHubProxy = $global:useGitHubProxy
        SelectedGitHubProxy = $global:selectedGitHubProxy
        SkipPathDialog = $global:skipPathDialog
        GitBashPath = $global:gitBashPath
        SaveTime = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
        Version = $global:appVersion
    }
    try {
        $config | ConvertTo-Json | Set-Content -Path $configPath -Encoding UTF8
        # 同时保存到工作空间
        if ($global:workspacePath -and (Test-Path $global:workspacePath)) {
            $workspaceConfig = Join-Path $global:workspacePath "manager-config.json"
            $config | ConvertTo-Json | Set-Content -Path $workspaceConfig -Encoding UTF8
        }
    } catch {
        Write-Host "保存配置失败: $($_.Exception.Message)" -ForegroundColor Yellow
    }
}

function Load-Config {
    $configPath = Initialize-Config
    if (Test-Path $configPath) {
        try {
            $config = Get-Content -Path $configPath -Encoding UTF8 | ConvertFrom-Json
            if ($config.LastInstallPath) { 
                $global:basePath = $config.LastInstallPath 
                if ($config.YunzaiDirName) {
                    $global:yunzaiDir = Join-Path $global:basePath $config.YunzaiDirName
                }
            }
            if ($config.UseGitHubProxy -ne $null) { $global:useGitHubProxy = $config.UseGitHubProxy }
            if ($config.SelectedGitHubProxy) { $global:selectedGitHubProxy = $config.SelectedGitHubProxy }
            if ($config.SkipPathDialog -ne $null) { $global:skipPathDialog = $config.SkipPathDialog }
            if ($config.GitBashPath -and (Test-Path $config.GitBashPath)) { 
                $global:gitBashPath = $config.GitBashPath 
            }
            # 验证路径是否存在
            if (-not (Test-Path $global:yunzaiDir)) {
                $global:skipPathDialog = $false
                $global:basePath = ""
                $global:yunzaiDir = ""
            }
        } catch {
            Write-Host "加载配置失败: $($_.Exception.Message)" -ForegroundColor Yellow
        }
    }
}
#endregion

#region 路径管理
function Initialize-Paths {
    param([string]$baseInstallPath, [string]$yunzaiDirName)
    $global:basePath = $baseInstallPath
    $global:yunzaiDir = Join-Path $global:basePath $yunzaiDirName
    $global:workspacePath = Join-Path $global:yunzaiDir "Yunzai-Workspace"
    $global:projectPath = Join-Path $global:workspacePath "XRK-Yunzai"
    $global:logPath = Join-Path $global:workspacePath "install.log"
    $global:softwarePath = Join-Path $global:workspacePath "software"
    $global:napCatPath = Join-Path $global:softwarePath "NapCat"
    
    # 创建必要的目录
    @($global:yunzaiDir, $global:workspacePath, $global:softwarePath, $global:napCatPath) | ForEach-Object {
        if (-not (Test-Path $_)) {
            New-Item -ItemType Directory -Path $_ -Force | Out-Null
        }
    }
}

function Find-GitBashPath {
    Write-Log "自动检测 Git Bash 路径..." -Color Cyan
    
    # 常见的Git安装路径
    $commonPaths = @(
        "C:\Program Files\Git\git-bash.exe",
        "C:\Program Files (x86)\Git\git-bash.exe",
        "$env:ProgramFiles\Git\git-bash.exe",
        "${env:ProgramFiles(x86)}\Git\git-bash.exe",
        "$env:LOCALAPPDATA\Programs\Git\git-bash.exe"
    )
    
    foreach ($path in $commonPaths) {
        if (Test-Path $path) {
            Write-Log "找到 Git Bash: $path" -Color Green
            return $path
        }
    }
    
    # 尝试从注册表查找
    try {
        $gitPaths = @()
        $keys = @(
            "HKLM:\SOFTWARE\GitForWindows",
            "HKLM:\SOFTWARE\WOW6432Node\GitForWindows",
            "HKCU:\Software\GitForWindows"
        )
        
        foreach ($key in $keys) {
            $keyData = Get-ItemProperty -Path $key -ErrorAction SilentlyContinue
            if ($keyData -and $keyData.InstallPath) {
                $gitPaths += $keyData.InstallPath
            }
        }
        
        foreach ($gitPath in $gitPaths) {
            $bashPath = Join-Path $gitPath "git-bash.exe"
            if (Test-Path $bashPath) {
                Write-Log "从注册表找到 Git Bash: $bashPath" -Color Green
                return $bashPath
            }
        }
    } catch {}
    
    Write-Log "无法自动检测到 Git Bash 路径" -Color Red
    return $null
}

function Initialize-GitBashPath {
    $detectedPath = Find-GitBashPath
    if ($detectedPath) {
        $global:gitBashPath = $detectedPath
        Write-ActionLog "Git Bash检测" "成功" "自动检测到路径: $detectedPath"
    } else {
        $global:gitBashPath = "C:\Program Files\Git\git-bash.exe"
        Write-ActionLog "Git Bash检测" "默认" "使用默认路径"
    }
}
#endregion

#region 日志系统
function Write-Log {
    param(
        [string]$message, 
        [switch]$NoConsole, 
        [string]$Color = "White"
    )
    $timestamp = Get-Date -Format "HH:mm:ss"
    $logMessage = "[$timestamp] $message"
    if (-not $NoConsole) {
        Write-Host $logMessage -ForegroundColor $Color
    }
    if ($global:logPath) {
        try {
            Add-Content -Path $global:logPath -Value $logMessage -Encoding UTF8 -ErrorAction SilentlyContinue
        } catch {}
    }
}

function Write-ActionLog {
    param(
        [string]$action, 
        [string]$result, 
        [string]$details = ""
    )
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logMessage = "[$timestamp] $action - $result"
    if ($details) { $logMessage += " - $details" }
    
    $color = switch($result) {
        "成功" { "Green" }
        "跳过" { "Yellow" }
        "失败" { "Red" }
        default { "Cyan" }
    }
    
    Write-Host $logMessage -ForegroundColor $color
    if ($global:logPath) {
        try {
            Add-Content -Path $global:logPath -Value $logMessage -Encoding UTF8 -ErrorAction SilentlyContinue
        } catch {}
    }
}
#endregion

#region UI辅助函数
function Get-AdaptiveFont {
    param(
        [int]$baseSize = 9, 
        [System.Drawing.FontStyle]$style = [System.Drawing.FontStyle]::Regular
    )
    $scaledSize = [Math]::Max(8, [Math]::Round($baseSize * $global:scaleFactor))
    return New-Object System.Drawing.Font("Microsoft YaHei UI", $scaledSize, $style)
}

function New-ModernButton {
    param(
        [string]$text, 
        [System.Drawing.Point]$location, 
        [System.Drawing.Size]$size = [System.Drawing.Size]::new(120, 40)
    )
    $backColor = $global:colors.Primary
    $hoverColor = [System.Drawing.Color]::FromArgb(
        [Math]::Max(0, $backColor.R - 20), 
        [Math]::Max(0, $backColor.G - 20), 
        [Math]::Max(0, $backColor.B - 20)
    )
    
    $button = New-Object System.Windows.Forms.Button
    $button.Text = $text
    $button.Location = $location
    $button.Size = $size
    $button.Font = Get-AdaptiveFont -baseSize 9 -style Bold
    $button.BackColor = $backColor
    $button.ForeColor = $global:colors.White
    $button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
    $button.FlatAppearance.BorderSize = 0
    $button.FlatAppearance.BorderColor = $backColor
    $button.Cursor = [System.Windows.Forms.Cursors]::Hand
    $button.UseVisualStyleBackColor = $false
    $button.TabStop = $false
    $button.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
    $button.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
    
    $button.Add_MouseEnter({ try { $this.BackColor = $hoverColor } catch {} })
    $button.Add_MouseLeave({ try { $this.BackColor = $backColor } catch {} })
    
    return $button
}

function New-ColoredButton {
    param(
        [string]$text, 
        [System.Drawing.Point]$location, 
        [System.Drawing.Size]$size, 
        [System.Drawing.Color]$buttonColor
    )
    $hoverColor = [System.Drawing.Color]::FromArgb(
        [Math]::Max(0, $buttonColor.R - 20), 
        [Math]::Max(0, $buttonColor.G - 20), 
        [Math]::Max(0, $buttonColor.B - 20)
    )
    
    $button = New-Object System.Windows.Forms.Button
    $button.Text = $text
    $button.Location = $location
    $button.Size = $size
    $button.Font = Get-AdaptiveFont -baseSize 9 -style Bold
    $button.BackColor = $buttonColor
    $button.ForeColor = $global:colors.White
    $button.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
    $button.FlatAppearance.BorderSize = 0
    $button.FlatAppearance.BorderColor = $buttonColor
    $button.Cursor = [System.Windows.Forms.Cursors]::Hand
    $button.UseVisualStyleBackColor = $false
    $button.TabStop = $false
    $button.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
    $button.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
    
    $button.Add_MouseEnter({ try { $this.BackColor = $hoverColor } catch {} })
    $button.Add_MouseLeave({ try { $this.BackColor = $buttonColor } catch {} })
    
    return $button
}

function New-ModernGroupBox {
    param(
        [string]$text, 
        [System.Drawing.Point]$location, 
        [System.Drawing.Size]$size
    )
    $groupBox = New-Object System.Windows.Forms.GroupBox
    $groupBox.Text = $text
    $groupBox.Location = $location
    $groupBox.Size = $size
    $groupBox.Font = Get-AdaptiveFont -baseSize 10 -style Bold
    $groupBox.ForeColor = $global:colors.Dark
    $groupBox.BackColor = $global:colors.White
    $groupBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                      [System.Windows.Forms.AnchorStyles]::Left -bor 
                      [System.Windows.Forms.AnchorStyles]::Right
    return $groupBox
}

function New-ScrollableTextBox {
    param(
        [System.Drawing.Point]$location, 
        [System.Drawing.Size]$size, 
        [string]$text = "", 
        [bool]$readOnly = $true
    )
    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Location = $location
    $textBox.Size = $size
    $textBox.Font = Get-AdaptiveFont -baseSize 9
    $textBox.Text = $text
    $textBox.ReadOnly = $readOnly
    $textBox.Multiline = $true
    $textBox.WordWrap = $true
    $textBox.ScrollBars = [System.Windows.Forms.ScrollBars]::Vertical
    $textBox.BackColor = $global:colors.White
    $textBox.BorderStyle = [System.Windows.Forms.BorderStyle]::FixedSingle
    $textBox.ForeColor = $global:colors.Dark
    $textBox.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                      [System.Windows.Forms.AnchorStyles]::Left -bor 
                      [System.Windows.Forms.AnchorStyles]::Right
    $textBox.TabStop = $false
    $textBox.Add_Enter({ $this.SelectionLength = 0 })
    $textBox.Add_GotFocus({ $this.SelectionLength = 0 })
    return $textBox
}

function Update-Status {
    param(
        [string]$message, 
        [System.Drawing.Color]$color = $null
    )
    if ($color -eq $null) { $color = $global:colors.Dark }
    if ($script:statusLabel) {
        try {
            $script:statusLabel.Text = $message
            $script:statusLabel.ForeColor = $color
            $script:statusLabel.Refresh()
            [System.Windows.Forms.Application]::DoEvents()
        } catch {
            Write-Host "状态更新: $message"
        }
    }
}
#endregion

#region 环境检测函数
function Test-NodeJS {
    try {
        $version = & node --version 2>$null
        if ($version -and ([System.Version]::new($version.TrimStart('v')) -ge [System.Version]::new("18.14.0"))) {
            return $true
        }
    } catch {}
    return $false
}

function Test-Pnpm {
    try {
        $npmListOutput = & cmd.exe /c "npm list -g pnpm" 2>$null
        if ($npmListOutput -and $npmListOutput -notmatch "empty") {
            return $true
        }
        return $false
    } catch {
        return $false
    }
}

function Test-Git {
    try {
        $null = & git --version 2>$null
        return $LASTEXITCODE -eq 0
    } catch {
        return $false
    }
}

function Test-Redis {
    try {
        $service = Get-Service -Name "Redis" -ErrorAction SilentlyContinue
        return $service -ne $null
    } catch {
        return $false
    }
}

function Test-FFmpeg {
    try {
        $null = & ffmpeg -version 2>$null
        return $LASTEXITCODE -eq 0
    } catch {
        return $false
    }
}

function Test-NapCatQQ {
    $napCatExePath = Join-Path $global:napCatPath "NapCatQQ-Desktop.exe"
    return Test-Path $napCatExePath
}

function Test-NapCatProcess {
    try {
        $process = Get-Process -Name "NapCatQQ-Desktop" -ErrorAction SilentlyContinue
        return $process -ne $null
    } catch {
        return $false
    }
}

function Test-Environment {
    $results = @{
        NodeJS = Test-NodeJS
        Pnpm = Test-Pnpm
        Git = Test-Git
        Redis = Test-Redis
        FFmpeg = Test-FFmpeg
        NapCatQQ = Test-NapCatQQ
        NapCatRunning = Test-NapCatProcess
    }
    
    $nodeVersion = if ($results.NodeJS) { 
        try { (& node --version 2>$null) } catch { "未知版本" } 
    } else { "" }
    
    $gitVersion = if ($results.Git) { 
        try { (& git --version 2>$null) } catch { "未知版本" } 
    } else { "" }
    
    $gitBashStatus = if (Test-Path $global:gitBashPath) { 
        "[√] 已检测到" 
    } else { 
        "[×] 未检测到" 
    }
    
    $statusText = "=== 环境检测结果 ===`r`n"
    $statusText += "Node.js: $(if($results.NodeJS){"[√] 已安装 $nodeVersion"}else{'[×] 未安装'})`r`n"
    $statusText += "pnpm: $(if($results.Pnpm){"[√] 已安装"}else{'[×] 未安装'})`r`n"
    $statusText += "Git: $(if($results.Git){"[√] 已安装"}else{'[×] 未安装'})`r`n"
    $statusText += "Git Bash: $gitBashStatus`r`n"
    $statusText += "Redis: $(if($results.Redis){'[√] 已安装'}else{'[×] 未安装'})`r`n"
    $statusText += "FFmpeg: $(if($results.FFmpeg){'[√] 已安装'}else{'[×] 未安装'})`r`n"
    $statusText += "NapCatQQ: $(if($results.NapCatQQ){"[√] 已下载"}else{'[×] 未下载'})"
    if ($results.NapCatRunning) { $statusText += " [运行中]" }
    
    return @{ Results = $results; StatusText = $statusText }
}
#endregion

#region 网络下载函数
function Get-ProxyUrl {
    param([string]$originalUrl)
    if ($originalUrl -match "github\.com" -and $global:useGitHubProxy) {
        return $global:selectedGitHubProxy + $originalUrl
    }
    return $originalUrl
}

function Download-FileWithProgress {
    param(
        [string]$url, 
        [string]$outFile, 
        [string]$description,
        [int]$timeoutSeconds = $global:downloadTimeout
    )
    
    try {
        $downloadUrl = Get-ProxyUrl -originalUrl $url
        Write-Log "开始下载 $description" -Color Cyan
        Write-Log "下载地址: $downloadUrl" -Color Gray
        Write-Log "保存位置: $outFile" -Color Gray
        Update-Status "正在下载 $description..." $global:colors.Primary
        
        # 创建WebClient用于下载
        $webClient = New-Object System.Net.WebClient
        $webClient.Headers.Add("User-Agent", "Mozilla/5.0")
        
        # 进度事件处理
        $Global:downloadComplete = $false
        $Global:downloadError = $null
        
        $webClient.add_DownloadProgressChanged({
            param($sender, $e)
            $percentComplete = $e.ProgressPercentage
            $receivedBytes = $e.BytesReceived
            $totalBytes = $e.TotalBytesToReceive
            
            if ($totalBytes -gt 0) {
                $receivedMB = [Math]::Round($receivedBytes / 1MB, 2)
                $totalMB = [Math]::Round($totalBytes / 1MB, 2)
                $progressText = "下载进度: $receivedMB MB / $totalMB MB ($percentComplete%)"
                Write-Progress -Activity "下载 $description" -Status $progressText -PercentComplete $percentComplete
            }
        })
        
        $webClient.add_DownloadFileCompleted({
            param($sender, $e)
            if ($e.Error) {
                $Global:downloadError = $e.Error
            }
            $Global:downloadComplete = $true
        })
        
        # 开始异步下载
        $webClient.DownloadFileAsync($downloadUrl, $outFile)
        
        # 等待下载完成
        $startTime = Get-Date
        while (-not $Global:downloadComplete) {
            $elapsed = (Get-Date) - $startTime
            if ($elapsed.TotalSeconds -gt $timeoutSeconds) {
                $webClient.CancelAsync()
                throw "下载超时"
            }
            Start-Sleep -Milliseconds 100
            [System.Windows.Forms.Application]::DoEvents()
        }
        
        # 清理进度条
        Write-Progress -Activity "下载 $description" -Completed
        
        if ($Global:downloadError) {
            throw $Global:downloadError
        }
        
        if (Test-Path $outFile) {
            Update-Status "$description 下载完成！" $global:colors.Success
            Write-Log "$description 下载成功" -Color Green
            Write-ActionLog "下载$description" "成功" "文件已保存"
            return $true
        } else {
            throw "下载的文件不存在"
        }
    } catch {
        Update-Status "$description 下载失败" $global:colors.Danger
        Write-Log "$description 下载失败: $($_.Exception.Message)" -Color Red
        Write-ActionLog "下载$description" "失败" $_.Exception.Message
        return $false
    } finally {
        if ($webClient) {
            $webClient.Dispose()
        }
    }
}
#endregion

#region 软件安装函数
function Check-ExistingInstallation {
    param(
        [string]$softwareName,
        [string]$installerPath
    )
    
    if (Test-Path $installerPath) {
        $result = [System.Windows.Forms.MessageBox]::Show(
            "检测到 $softwareName 安装文件已存在。`n是否删除旧文件并重新下载？", 
            "发现旧文件", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        
        if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
            try {
                Remove-Item -Path $installerPath -Force
                Write-ActionLog "$softwareName清理" "成功" "已删除旧安装文件"
                return $true
            } catch {
                Write-ActionLog "$softwareName清理" "失败" $_.Exception.Message
                return $false
            }
        } else {
            return $false
        }
    }
    return $true
}

function Install-WithBackgroundProcess {
    param(
        [string]$installerPath,
        [string]$processName,
        [string]$displayName
    )
    
    try {
        Update-Status "$displayName 安装程序已启动，请在弹出窗口中完成安装" $global:colors.Primary
        Write-ActionLog "$displayName安装" "进行中" "启动安装程序"
        
        $process = Start-Process -FilePath $installerPath -PassThru
        
        # 等待安装完成
        $maxWaitTime = 300 # 最多等待5分钟
        $waited = 0
        while (-not $process.HasExited -and $waited -lt $maxWaitTime) {
            Start-Sleep -Seconds 1
            $waited++
            [System.Windows.Forms.Application]::DoEvents()
        }
        
        # 刷新环境变量
        $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + 
                   [System.Environment]::GetEnvironmentVariable("Path", "User")
        
        Update-Status "$displayName 安装程序已完成" $global:colors.Success
        Write-ActionLog "$displayName安装" "完成" "安装程序已退出"
        return $true
    } catch {
        Update-Status "$displayName 安装失败" $global:colors.Danger
        Write-ActionLog "$displayName安装" "失败" $_.Exception.Message
        return $false
    }
}

function Install-NodeJS {
    Write-ActionLog "Node.js安装" "开始" "检查当前安装状态"
    
    if (Test-NodeJS) {
        $currentVersion = & node --version 2>$null
        $result = [System.Windows.Forms.MessageBox]::Show(
            "系统已安装 Node.js $currentVersion`n是否重新安装？", 
            "Node.js 已安装", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::No) {
            Write-ActionLog "Node.js安装" "跳过" "用户选择保留现有版本"
            return $true
        }
    }
    
    $nodePath = Join-Path $global:softwarePath "node-installer.msi"
    
    if (-not (Check-ExistingInstallation "Node.js" $nodePath)) {
        return $true
    }
    
    if (-not (Test-Path $nodePath)) {
        $downloadSuccess = Download-FileWithProgress `
            "https://nodejs.org/dist/v23.5.0/node-v23.5.0-x64.msi" `
            $nodePath `
            "Node.js v23安装包" `
            -timeoutSeconds 120
            
        if (-not $downloadSuccess) {
            [System.Windows.Forms.MessageBox]::Show(
                "Node.js下载失败，请检查网络连接", 
                "下载失败", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Error
            )
            return $false
        }
    }
    
    return Install-WithBackgroundProcess $nodePath "Node.js" "Node.js"
}

function Install-Pnpm {
    Write-ActionLog "pnpm安装" "开始" "检查当前安装状态"
    
    if (Test-Pnpm) { 
        $result = [System.Windows.Forms.MessageBox]::Show(
            "系统已安装 pnpm`n是否重新安装？", 
            "pnpm 已安装", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::No) {
            Write-ActionLog "pnpm安装" "跳过" "用户选择保留现有版本"
            return $true
        }
    }
    
    if (-not (Test-NodeJS)) { 
        Update-Status "请先安装Node.js" $global:colors.Danger
        Write-ActionLog "pnpm安装" "失败" "Node.js未安装"
        return $false 
    }
    
    try {
        Update-Status "正在安装pnpm..." $global:colors.Primary
        Write-Log "开始安装pnpm" -Color Cyan
        
        # 设置执行策略
        Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
        
        # 卸载旧版本（如果存在）
        Write-Log "清理旧版本pnpm..." -Color Gray
        & cmd.exe /c "npm rm -g pnpm" 2>$null
        
        # 安装新版本
        Write-Log "安装最新版pnpm..." -Color Cyan
        $result = & cmd.exe /c "npm install -g pnpm@latest" 2>&1
        
        if ($LASTEXITCODE -eq 0) {
            # 刷新环境变量
            $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + 
                       [System.Environment]::GetEnvironmentVariable("Path", "User")
            Start-Sleep -Seconds 2
            
            if (Test-Pnpm) {
                Update-Status "pnpm安装成功！" $global:colors.Success
                Write-Log "pnpm安装成功" -Color Green
                Write-ActionLog "pnpm安装" "成功" "pnpm已成功安装"
                return $true
            }
        }
        
        throw "pnpm安装失败"
    } catch {
        Update-Status "pnpm安装失败，请手动安装" $global:colors.Danger
        Write-ActionLog "pnpm安装" "失败" $_.Exception.Message
        
        $manualSolution = @"
pnpm自动安装失败，请手动完成安装：

1. 以管理员身份打开命令提示符（cmd）
2. 执行：npm install -g pnpm@latest
3. 重启程序检查pnpm状态

常见问题：
- 确保Node.js已正确安装
- 检查网络连接是否正常
- 尝试使用npm代理：npm config set registry https://registry.npmmirror.com
"@
        [System.Windows.Forms.MessageBox]::Show(
            $manualSolution, 
            "pnpm手动安装指南", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Information
        )
        return $false
    }
}

function Install-Git {
    Write-ActionLog "Git安装" "开始" "检查当前安装状态"
    
    if (Test-Git) { 
        try {
            $gitVersion = & git --version 2>$null
            $result = [System.Windows.Forms.MessageBox]::Show(
                "系统已安装 $gitVersion`n是否重新安装？", 
                "Git 已安装", 
                [System.Windows.Forms.MessageBoxButtons]::YesNo, 
                [System.Windows.Forms.MessageBoxIcon]::Question
            )
            if ($result -eq [System.Windows.Forms.DialogResult]::No) {
                Write-ActionLog "Git安装" "跳过" "用户选择保留现有版本"
                return $true
            }
        } catch {
            Write-ActionLog "Git状态检查" "跳过" "系统已安装Git"
            return $true
        }
    }
    
    $gitPath = Join-Path $global:softwarePath "git-installer.exe"
    
    if (-not (Check-ExistingInstallation "Git" $gitPath)) {
        return $true
    }
    
    if (-not (Test-Path $gitPath)) {
        $downloadSuccess = Download-FileWithProgress `
            "https://github.com/git-for-windows/git/releases/download/v2.47.1.windows.1/Git-2.47.1-64-bit.exe" `
            $gitPath `
            "Git安装包" `
            -timeoutSeconds 120
            
        if (-not $downloadSuccess) {
            [System.Windows.Forms.MessageBox]::Show(
                "Git下载失败，请检查网络连接", 
                "下载失败", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Error
            )
            return $false
        }
    }
    
    $result = Install-WithBackgroundProcess $gitPath "Git" "Git"
    if ($result) {
        # 重新检测Git Bash路径
        Initialize-GitBashPath
        Save-Config
    }
    return $result
}

function Install-Redis {
    Write-ActionLog "Redis安装" "开始" "检查当前安装状态"
    
    if (Test-Redis) {
        $result = [System.Windows.Forms.MessageBox]::Show(
            "系统已安装 Redis 服务`n是否重新安装？", 
            "Redis 已安装", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::No) {
            Write-ActionLog "Redis安装" "跳过" "用户选择保留现有版本"
            return $true
        }
    }
    
    $redisPath = Join-Path $global:softwarePath "redis-installer.msi"
    
    if (-not (Check-ExistingInstallation "Redis" $redisPath)) {
        return $true
    }
    
    if (-not (Test-Path $redisPath)) {
        $downloadSuccess = Download-FileWithProgress `
            "https://github.com/tporadowski/redis/releases/download/v5.0.14.1/Redis-x64-5.0.14.1.msi" `
            $redisPath `
            "Redis安装包" `
            -timeoutSeconds 60
            
        if (-not $downloadSuccess) {
            [System.Windows.Forms.MessageBox]::Show(
                "Redis下载失败，请检查网络连接", 
                "下载失败", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Error
            )
            return $false
        }
    }
    
    return Install-WithBackgroundProcess $redisPath "Redis" "Redis"
}

function Install-FFmpeg {
    Write-ActionLog "FFmpeg安装" "开始" "检查当前安装状态"
    
    if (Test-FFmpeg) {
        $result = [System.Windows.Forms.MessageBox]::Show(
            "系统已安装 FFmpeg`n是否重新安装？", 
            "FFmpeg 已安装", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::No) {
            Write-ActionLog "FFmpeg安装" "跳过" "用户选择保留现有版本"
            return $true
        }
    }
    
    $ffmpegZipPath = Join-Path $global:softwarePath "ffmpeg.zip"
    $ffmpegExtractPath = Join-Path $global:softwarePath "ffmpeg"
    
    if (-not (Check-ExistingInstallation "FFmpeg" $ffmpegZipPath)) {
        return $true
    }
    
    if (-not (Test-Path $ffmpegZipPath)) {
        $ffmpegUrl = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip"
        $downloadSuccess = Download-FileWithProgress $ffmpegUrl $ffmpegZipPath "FFmpeg安装包" -timeoutSeconds 180
        
        if (-not $downloadSuccess) {
            # 尝试备用源
            Write-Log "尝试备用下载源..." -Color Yellow
            $ffmpegUrl = "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2024-12-01-13-05/ffmpeg-n7.0-latest-win64-gpl-7.0.zip"
            $downloadSuccess = Download-FileWithProgress $ffmpegUrl $ffmpegZipPath "FFmpeg安装包(备用)" -timeoutSeconds 180
            
            if (-not $downloadSuccess) {
                [System.Windows.Forms.MessageBox]::Show(
                    "FFmpeg下载失败，请检查网络连接", 
                    "下载失败", 
                    [System.Windows.Forms.MessageBoxButtons]::OK, 
                    [System.Windows.Forms.MessageBoxIcon]::Error
                )
                return $false
            }
        }
    }
    
    try {
        Update-Status "正在解压FFmpeg..." $global:colors.Primary
        Write-ActionLog "FFmpeg安装" "进行中" "解压FFmpeg安装包"
        
        # 清理旧的解压目录
        if (Test-Path $ffmpegExtractPath) {
            Remove-Item -Path $ffmpegExtractPath -Recurse -Force
        }
        
        # 解压文件
        Add-Type -AssemblyName System.IO.Compression.FileSystem
        [System.IO.Compression.ZipFile]::ExtractToDirectory($ffmpegZipPath, $ffmpegExtractPath)
        
        # 查找bin目录
        $ffmpegBinPath = $null
        $extractedDirs = Get-ChildItem -Path $ffmpegExtractPath -Directory
        foreach ($dir in $extractedDirs) {
            $binPath = Join-Path $dir.FullName "bin"
            if (Test-Path $binPath) {
                $ffmpegBinPath = $binPath
                break
            }
        }
        
        if (-not $ffmpegBinPath) {
            throw "找不到FFmpeg的bin目录"
        }
        
        Write-Log "找到FFmpeg bin目录: $ffmpegBinPath" -Color Green
        Write-ActionLog "FFmpeg安装" "进行中" "配置环境变量"
        
        # 添加到系统环境变量
        $machinePath = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
        if ($machinePath -notlike "*$ffmpegBinPath*") {
            [System.Environment]::SetEnvironmentVariable("Path", "$machinePath;$ffmpegBinPath", "Machine")
            Write-Log "已将FFmpeg添加到系统环境变量" -Color Green
        }
        
        # 刷新环境变量
        $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + 
                   [System.Environment]::GetEnvironmentVariable("Path", "User")
        
        Update-Status "FFmpeg安装成功！" $global:colors.Success
        Write-ActionLog "FFmpeg安装" "成功" "FFmpeg已成功安装并配置"
        return $true
    } catch {
        Update-Status "FFmpeg安装失败" $global:colors.Danger
        Write-ActionLog "FFmpeg安装" "失败" $_.Exception.Message
        
        $errorDetails = @"
FFmpeg安装失败：$($_.Exception.Message)

请尝试手动安装：
1. 从 https://github.com/BtbN/FFmpeg-Builds/releases 下载
2. 解压后将bin目录添加到系统环境变量PATH中
3. 重启电脑使环境变量生效
"@
        [System.Windows.Forms.MessageBox]::Show(
            $errorDetails, 
            "FFmpeg安装错误", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Error
        )
        return $false
    }
}

function Install-NapCatQQ {
    Write-ActionLog "NapCatQQ下载" "开始" "检查当前下载状态"
    
    if (-not (Test-Path $global:napCatPath)) {
        New-Item -ItemType Directory -Path $global:napCatPath -Force | Out-Null
        Write-Log "创建NapCat目录: $global:napCatPath" -Color Gray
    }
    
    $napCatExePath = Join-Path $global:napCatPath "NapCatQQ-Desktop.exe"
    
    if (Test-Path $napCatExePath) {
        $result = [System.Windows.Forms.MessageBox]::Show(
            "NapCatQQ 已存在`n是否重新下载？", 
            "文件已存在", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::No) {
            Write-ActionLog "NapCatQQ下载" "跳过" "用户选择保留现有文件"
            return $true
        } else {
            try {
                Remove-Item -Path $napCatExePath -Force
                Write-ActionLog "NapCatQQ清理" "成功" "已删除旧文件"
            } catch {
                Write-ActionLog "NapCatQQ清理" "失败" $_.Exception.Message
            }
        }
    }
    
    $downloadSuccess = Download-FileWithProgress `
        "https://github.com/NapNeko/NapCatQQ-Desktop/releases/download/v1.5.4/NapCatQQ-Desktop.exe" `
        $napCatExePath `
        "NapCatQQ一键端" `
        -timeoutSeconds 90
        
    if ($downloadSuccess) {
        Update-Status "NapCatQQ下载成功！" $global:colors.Success
        Write-ActionLog "NapCatQQ下载" "成功" "文件已保存"
        return $true
    } else {
        Write-ActionLog "NapCatQQ下载" "失败" "下载失败"
        return $false
    }
}
#endregion

#region 项目管理函数
function Clone-XRKYunzai {
    Write-ActionLog "项目克隆" "开始" "检查项目目录状态"
    
    if (Test-Path $global:projectPath) {
        $files = Get-ChildItem $global:projectPath -Force -ErrorAction SilentlyContinue
        if ($files) {
            $result = [System.Windows.Forms.MessageBox]::Show(
                "项目目录已存在`n是否删除并重新克隆？", 
                "项目已存在", 
                [System.Windows.Forms.MessageBoxButtons]::YesNo, 
                [System.Windows.Forms.MessageBoxIcon]::Question
            )
            if ($result -eq [System.Windows.Forms.DialogResult]::No) {
                Write-ActionLog "项目克隆" "跳过" "用户选择保留现有项目"
                return $true
            } else {
                try {
                    Remove-Item -Path $global:projectPath -Recurse -Force
                    Write-ActionLog "项目清理" "成功" "已删除旧项目"
                } catch {
                    Write-ActionLog "项目清理" "失败" $_.Exception.Message
                    return $false
                }
            }
        }
    }
    
    if (-not (Test-Git)) {
        Update-Status "请先安装Git" $global:colors.Danger
        Write-ActionLog "项目克隆" "失败" "Git未安装"
        [System.Windows.Forms.MessageBox]::Show(
            "请先在环境安装中安装Git", 
            "Git未安装", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Warning
        )
        return $false
    }
    
    try {
        Update-Status "正在克隆项目，请稍候..." $global:colors.Primary
        Write-Log "开始克隆XRK-Yunzai项目" -Color Cyan
        Write-ActionLog "项目克隆" "进行中" "从GitCode克隆"
        
        # 配置git长路径支持
        & git config --global core.longpaths true 2>$null
        
        # 切换到工作目录
        Set-Location $global:workspacePath
        
        # 执行克隆
        Write-Log "执行克隆命令..." -Color Gray
        $result = & git clone --depth=1 --progress "https://gitcode.com/Xrkseek/XRK-Yunzai.git" "$global:projectPath" 2>&1
        
        if ($LASTEXITCODE -eq 0) {
            Update-Status "项目克隆成功！" $global:colors.Success
            Write-Log "项目克隆成功" -Color Green
            Write-ActionLog "项目克隆" "成功" "项目已克隆"
            return $true
        } else {
            throw "Git克隆失败: $result"
        }
    } catch {
        Update-Status "克隆项目失败" $global:colors.Danger
        Write-ActionLog "项目克隆" "失败" $_.Exception.Message
        
        [System.Windows.Forms.MessageBox]::Show(
            "项目克隆失败: $($_.Exception.Message)`n`n请检查网络连接或手动克隆", 
            "克隆失败", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Error
        )
        return $false
    }
}

function Start-NapCatQQ {
    Write-ActionLog "NapCatQQ启动" "开始" "检查程序文件"
    $napCatExePath = Join-Path $global:napCatPath "NapCatQQ-Desktop.exe"
    
    if (-not (Test-Path $napCatExePath)) {
        Update-Status "请先下载NapCatQQ" $global:colors.Danger
        Write-ActionLog "NapCatQQ启动" "失败" "程序文件不存在"
        [System.Windows.Forms.MessageBox]::Show(
            "请先在环境安装中下载NapCatQQ", 
            "NapCatQQ未找到", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Warning
        )
        return $false
    }
    
    if (Test-NapCatProcess) {
        Update-Status "NapCatQQ已经在运行中" $global:colors.Warning
        Write-ActionLog "NapCatQQ启动" "跳过" "程序已在运行"
        return $false
    }
    
    try {
        Start-Process -FilePath $napCatExePath -WorkingDirectory $global:napCatPath
        
        Update-Status "NapCatQQ已启动！" $global:colors.Success
        Write-Log "NapCatQQ已启动 (工作目录: $global:napCatPath)" -Color Green
        Write-ActionLog "NapCatQQ启动" "成功" "程序已启动"
        
        # 刷新环境状态
        Start-Sleep -Seconds 1
        $envResult = Test-Environment
        $global:envStatusTextBox.Text = $envResult.StatusText
        return $true
    } catch {
        Update-Status "NapCatQQ启动失败" $global:colors.Danger
        Write-ActionLog "NapCatQQ启动" "失败" $_.Exception.Message
        return $false
    }
}

function Start-XRKYunzai {
    Write-ActionLog "XRK-Yunzai启动" "开始" "检查项目文件"
    $appJsPath = Join-Path $global:projectPath "app.js"
    
    if (-not (Test-Path $appJsPath)) {
        Update-Status "项目文件不存在，请先克隆项目" $global:colors.Danger
        Write-ActionLog "XRK-Yunzai启动" "失败" "app.js不存在"
        [System.Windows.Forms.MessageBox]::Show(
            "请先克隆项目", 
            "项目未部署", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Warning
        )
        return $false
    }
    
    try {
        # 使用CMD启动，保持窗口打开
        $cmdCommand = "cd /d `"$global:projectPath`" && node app"
        Start-Process -FilePath "cmd.exe" -ArgumentList "/k", $cmdCommand -WorkingDirectory $global:projectPath
        
        Update-Status "XRK-Yunzai已启动！" $global:colors.Success
        Write-Log "XRK-Yunzai已启动 (工作目录: $global:projectPath)" -Color Green
        Write-ActionLog "XRK-Yunzai启动" "成功" "已启动"
        return $true
    } catch {
        Update-Status "XRK-Yunzai启动失败" $global:colors.Danger
        Write-ActionLog "XRK-Yunzai启动" "失败" $_.Exception.Message
        
        $manualInstructions = @"
启动失败，请手动启动：

1. 打开命令提示符（CMD）
2. 执行以下命令：
   cd /d "$global:projectPath"
   node app

如果启动失败，请检查：
- Node.js是否正确安装
- 项目依赖是否已安装（pnpm install）
"@
        [System.Windows.Forms.MessageBox]::Show(
            $manualInstructions, 
            "手动启动指南", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Information
        )
        return $false
    }
}
#endregion

#region 更新系统
function Check-ForUpdates {
    try {
        Write-Log "检查程序更新..." -Color Cyan
        Update-Status "检查程序更新..." $global:colors.Primary
        
        $result = [System.Windows.Forms.MessageBox]::Show(
            "是否下载最新版本的葵崽专属管理器？`n`n当前版本: v$global:appVersion`n`n更新后将自动替换当前程序",
            "检查更新",
            [System.Windows.Forms.MessageBoxButtons]::YesNo,
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        
        if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
            return $true
        }
        
        Update-Status "用户取消更新" $global:colors.Secondary
        return $false
    } catch {
        Update-Status "更新检查失败" $global:colors.Danger
        Write-Log "更新检查失败: $($_.Exception.Message)" -Color Red
        return $false
    }
}

function Perform-Update {
    try {
        Write-Log "开始自动更新程序..." -Color Cyan
        Update-Status "正在下载最新版本..." $global:colors.Primary
        
        $currentExe = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
        $tempPath = [System.IO.Path]::GetTempPath()
        $downloadPath = Join-Path $tempPath "YunzaiManager_new.exe"
        
        # 下载新版本
        $downloadUrl = Get-ProxyUrl -originalUrl $global:updateUrl
        Write-Log "下载地址: $downloadUrl" -Color Gray
        Write-Log "临时保存位置: $downloadPath" -Color Gray
        
        $downloadSuccess = Download-FileWithProgress $downloadUrl $downloadPath "程序更新" -timeoutSeconds 300
        
        if ($downloadSuccess -and (Test-Path $downloadPath)) {
            Write-Log "下载完成，准备自动更新..." -Color Green
            Update-Status "准备自动更新..." $global:colors.Success
            Write-ActionLog "程序更新" "成功" "新版本已下载"
            
            # 创建更新脚本
            $updateScript = @"
@echo off
echo 正在更新葵崽专属管理器...
timeout /t 2 /nobreak > nul
move /y "$downloadPath" "$currentExe"
if %errorlevel% == 0 (
    echo 更新成功！正在启动新版本...
    start "" "$currentExe"
) else (
    echo 更新失败！请手动替换文件。
    pause
)
del "%~f0"
"@
            
            $updateBatPath = Join-Path $tempPath "update_yunzai_manager.bat"
            $updateScript | Out-File -FilePath $updateBatPath -Encoding ASCII
            
            # 显示更新提示
            [System.Windows.Forms.MessageBox]::Show(
                "新版本下载完成！`n`n点击确定后将自动更新并重启程序。",
                "自动更新",
                [System.Windows.Forms.MessageBoxButtons]::OK,
                [System.Windows.Forms.MessageBoxIcon]::Information
            )
            
            # 启动更新脚本并退出当前程序
            Start-Process -FilePath $updateBatPath -WindowStyle Hidden
            [System.Environment]::Exit(0)
        }
    } catch {
        Update-Status "更新失败" $global:colors.Danger
        Write-Log "更新失败: $($_.Exception.Message)" -Color Red
        Write-ActionLog "程序更新" "失败" $_.Exception.Message
        
        [System.Windows.Forms.MessageBox]::Show(
            "自动更新失败: $($_.Exception.Message)`n`n请手动下载更新",
            "更新失败",
            [System.Windows.Forms.MessageBoxButtons]::OK,
            [System.Windows.Forms.MessageBoxIcon]::Error
        )
    }
}
#endregion

#region 对话框界面
function Get-InstallPath {
    $dialog = New-Object System.Windows.Forms.Form
    $dialog.Text = "选择安装位置 - 葵崽专属管理器"
    $dialog.Size = New-Object System.Drawing.Size(600, 500)
    $dialog.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $dialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
    $dialog.MaximizeBox = $false
    $dialog.BackColor = $global:colors.Light
    
    # 标题标签
    $titleLabel = New-Object System.Windows.Forms.Label
    $titleLabel.Text = "葵崽专属管理器 - 安装位置设置"
    $titleLabel.Font = Get-AdaptiveFont -baseSize 14 -style Bold
    $titleLabel.Location = New-Object System.Drawing.Point(20, 15)
    $titleLabel.Size = New-Object System.Drawing.Size(550, 30)
    $titleLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
    $titleLabel.ForeColor = $global:colors.Dark
    $dialog.Controls.Add($titleLabel)
    
    # 父目录选择
    $parentLabel = New-Object System.Windows.Forms.Label
    $parentLabel.Text = "选择父目录:"
    $parentLabel.Location = New-Object System.Drawing.Point(20, 60)
    $parentLabel.Size = New-Object System.Drawing.Size(80, 25)
    $parentLabel.Font = Get-AdaptiveFont -baseSize 10
    $dialog.Controls.Add($parentLabel)
    
    $parentTextBox = New-Object System.Windows.Forms.TextBox
    $defaultParent = if ($global:basePath) { $global:basePath } else { "$env:USERPROFILE\Desktop" }
    $parentTextBox.Text = $defaultParent
    $parentTextBox.Location = New-Object System.Drawing.Point(110, 60)
    $parentTextBox.Size = New-Object System.Drawing.Size(350, 25)
    $parentTextBox.Font = Get-AdaptiveFont -baseSize 9
    $parentTextBox.ReadOnly = $true
    $parentTextBox.BackColor = $global:colors.White
    $dialog.Controls.Add($parentTextBox)
    
    $browseButton = New-ModernButton "浏览" ([System.Drawing.Point]::new(470, 58)) ([System.Drawing.Size]::new(70, 28))
    $browseButton.Add_Click({
        $folderDialog = New-Object System.Windows.Forms.FolderBrowserDialog
        $folderDialog.Description = "选择葵崽安装的父目录"
        $folderDialog.SelectedPath = $parentTextBox.Text
        if ($folderDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
            $parentTextBox.Text = $folderDialog.SelectedPath
        }
    })
    $dialog.Controls.Add($browseButton)
    
    # 目录名称输入
    $dirLabel = New-Object System.Windows.Forms.Label
    $dirLabel.Text = "葵崽目录名:"
    $dirLabel.Location = New-Object System.Drawing.Point(20, 100)
    $dirLabel.Size = New-Object System.Drawing.Size(80, 25)
    $dirLabel.Font = Get-AdaptiveFont -baseSize 10
    $dialog.Controls.Add($dirLabel)
    
    $dirTextBox = New-Object System.Windows.Forms.TextBox
    $defaultDirName = if ($global:yunzaiDir) { Split-Path $global:yunzaiDir -Leaf } else { "葵崽机器人" }
    $dirTextBox.Text = $defaultDirName
    $dirTextBox.Location = New-Object System.Drawing.Point(110, 100)
    $dirTextBox.Size = New-Object System.Drawing.Size(350, 25)
    $dirTextBox.Font = Get-AdaptiveFont -baseSize 9
    $dialog.Controls.Add($dirTextBox)
    
    # 记住设置选项
    $skipCheckBox = New-Object System.Windows.Forms.CheckBox
    $skipCheckBox.Text = "记住设置，以后不再询问路径"
    $skipCheckBox.Location = New-Object System.Drawing.Point(20, 140)
    $skipCheckBox.Size = New-Object System.Drawing.Size(400, 25)
    $skipCheckBox.Font = Get-AdaptiveFont -baseSize 10
    $skipCheckBox.ForeColor = $global:colors.Danger
    $skipCheckBox.Checked = $false
    $dialog.Controls.Add($skipCheckBox)
    
    # 目录结构说明
    $infoLabel = New-Object System.Windows.Forms.Label
    $infoLabel.Text = @"
目录结构预览:
父目录\
└── 葵崽目录\
    └── Yunzai-Workspace\
        ├── XRK-Yunzai\      (项目文件)
        ├── software\        (软件安装包)
        │   └── NapCat\      (NapCat程序)
        └── install.log      (安装日志)

重要说明:
• 建议选择空间充足的磁盘位置（至少需要2GB）
• 勾选"记住设置"后下次启动将直接使用此路径
• 需要更改路径请删除配置文件：
  %APPDATA%\Yunzai-Manager\config.json
"@
    $infoLabel.Location = New-Object System.Drawing.Point(20, 175)
    $infoLabel.Size = New-Object System.Drawing.Size(550, 250)
    $infoLabel.Font = Get-AdaptiveFont -baseSize 9
    $infoLabel.ForeColor = $global:colors.Dark
    $dialog.Controls.Add($infoLabel)
    
    # 确定取消按钮
    $okButton = New-ColoredButton "确定" ([System.Drawing.Point]::new(380, 440)) ([System.Drawing.Size]::new(70, 30)) $global:colors.Success
    $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $dialog.Controls.Add($okButton)
    
    $cancelButton = New-ColoredButton "取消" ([System.Drawing.Point]::new(460, 440)) ([System.Drawing.Size]::new(70, 30)) $global:colors.Secondary
    $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $dialog.Controls.Add($cancelButton)
    
    # 显示对话框
    $result = $dialog.ShowDialog()
    if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
        $parentPath = $parentTextBox.Text.TrimEnd('\')
        $dirName = $dirTextBox.Text.Trim()
        
        if ([string]::IsNullOrWhiteSpace($dirName)) {
            [System.Windows.Forms.MessageBox]::Show(
                "请输入葵崽目录名称", 
                "输入错误", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Warning
            )
            return Get-InstallPath
        }
        
        $global:skipPathDialog = $skipCheckBox.Checked
        Initialize-Paths -baseInstallPath $parentPath -yunzaiDirName $dirName
        Save-Config
        Write-ActionLog "路径设置" "成功" "父目录: $parentPath, 葵崽目录: $dirName"
        return $true
    }
    
    Write-ActionLog "路径设置" "取消" "用户取消路径设置"
    return $false
}

function Show-ProxyDialog {
    $dialog = New-Object System.Windows.Forms.Form
    $dialog.Text = "GitHub代理设置"
    $dialog.Size = New-Object System.Drawing.Size(500, 320)
    $dialog.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterParent
    $dialog.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
    $dialog.MaximizeBox = $false
    $dialog.BackColor = $global:colors.Light
    
    # 标题
    $titleLabel = New-Object System.Windows.Forms.Label
    $titleLabel.Text = "GitHub下载代理设置"
    $titleLabel.Font = Get-AdaptiveFont -baseSize 12 -style Bold
    $titleLabel.Location = New-Object System.Drawing.Point(20, 15)
    $titleLabel.Size = New-Object System.Drawing.Size(450, 25)
    $titleLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
    $dialog.Controls.Add($titleLabel)
    
    # 启用代理选项
    $enableCheckBox = New-Object System.Windows.Forms.CheckBox
    $enableCheckBox.Text = "启用GitHub代理加速下载"
    $enableCheckBox.Location = New-Object System.Drawing.Point(20, 60)
    $enableCheckBox.Size = New-Object System.Drawing.Size(250, 25)
    $enableCheckBox.Font = Get-AdaptiveFont -baseSize 10
    $enableCheckBox.Checked = $global:useGitHubProxy
    $dialog.Controls.Add($enableCheckBox)
    
    # 代理选择
    $proxyLabel = New-Object System.Windows.Forms.Label
    $proxyLabel.Text = "选择代理服务器:"
    $proxyLabel.Location = New-Object System.Drawing.Point(20, 95)
    $proxyLabel.Size = New-Object System.Drawing.Size(120, 25)
    $proxyLabel.Font = Get-AdaptiveFont -baseSize 9
    $dialog.Controls.Add($proxyLabel)
    
    $proxyComboBox = New-Object System.Windows.Forms.ComboBox
    $proxyComboBox.Location = New-Object System.Drawing.Point(20, 120)
    $proxyComboBox.Size = New-Object System.Drawing.Size(450, 25)
    $proxyComboBox.Font = Get-AdaptiveFont -baseSize 9
    $proxyComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
    
    foreach ($proxy in $global:githubProxies) {
        $proxyComboBox.Items.Add($proxy.Name)
    }
    
    $currentIndex = 0
    for ($i = 0; $i -lt $global:githubProxies.Count; $i++) {
        if ($global:githubProxies[$i].Url -eq $global:selectedGitHubProxy) {
            $currentIndex = $i
            break
        }
    }
    $proxyComboBox.SelectedIndex = $currentIndex
    $dialog.Controls.Add($proxyComboBox)
    
    # 说明文本
    $infoLabel = New-Object System.Windows.Forms.Label
    $infoLabel.Text = @"
说明: 
• 代理仅用于GitHub资源下载，提高国内访问速度
• 如果下载速度正常，可以关闭代理
• 不同代理服务器速度可能不同，请选择最快的
• 代理服务由第三方提供，请注意安全
"@
    $infoLabel.Location = New-Object System.Drawing.Point(20, 160)
    $infoLabel.Size = New-Object System.Drawing.Size(450, 80)
    $infoLabel.Font = Get-AdaptiveFont -baseSize 8
    $infoLabel.ForeColor = $global:colors.Dark
    $dialog.Controls.Add($infoLabel)
    
    # 按钮
    $okButton = New-ColoredButton "确定" ([System.Drawing.Point]::new(310, 250)) ([System.Drawing.Size]::new(70, 30)) $global:colors.Success
    $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $dialog.Controls.Add($okButton)
    
    $cancelButton = New-ColoredButton "取消" ([System.Drawing.Point]::new(390, 250)) ([System.Drawing.Size]::new(70, 30)) $global:colors.Secondary
    $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $dialog.Controls.Add($cancelButton)
    
    if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $global:useGitHubProxy = $enableCheckBox.Checked
        if ($proxyComboBox.SelectedIndex -ge 0) {
            $global:selectedGitHubProxy = $global:githubProxies[$proxyComboBox.SelectedIndex].Url
        }
        Save-Config
        
        $proxyStatus = if ($global:useGitHubProxy) { 
            "已启用 - $($global:selectedGitHubProxy)" 
        } else { 
            "已关闭" 
        }
        
        Write-ActionLog "代理设置" "成功" "代理状态: $proxyStatus"
        [System.Windows.Forms.MessageBox]::Show(
            "代理设置已保存", 
            "设置成功", 
            [System.Windows.Forms.MessageBoxButtons]::OK, 
            [System.Windows.Forms.MessageBoxIcon]::Information
        )
    }
}
#endregion

#region 主窗口
function Show-MainWindow {
    $form = New-Object System.Windows.Forms.Form
    $form.Text = "葵崽专属管理器 v$global:appVersion"
    $form.Size = New-Object System.Drawing.Size(1200, 800)
    $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
    $form.BackColor = $global:colors.Light
    $form.MinimumSize = New-Object System.Drawing.Size(960, 640)
    
    # 标题区域
    $titlePanel = New-Object System.Windows.Forms.Panel
    $titlePanel.Location = New-Object System.Drawing.Point(0, 0)
    $titlePanel.Size = New-Object System.Drawing.Size(1184, 100)
    $titlePanel.BackColor = $global:colors.White
    $titlePanel.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                         [System.Windows.Forms.AnchorStyles]::Left -bor 
                         [System.Windows.Forms.AnchorStyles]::Right
    $form.Controls.Add($titlePanel)
    
    # 标题文本
    $titleLabel = New-Object System.Windows.Forms.Label
    $titleLabel.Name = "titleLabel"
    $titleLabel.Text = "葵崽专属管理器"
    $titleLabel.Font = Get-AdaptiveFont -baseSize 20 -style Bold
    $titleLabel.Location = New-Object System.Drawing.Point(30, 20)
    $titleLabel.Size = New-Object System.Drawing.Size(400, 35)
    $titleLabel.ForeColor = $global:colors.Dark
    $titlePanel.Controls.Add($titleLabel)
    
    $subtitleLabel = New-Object System.Windows.Forms.Label
    $subtitleLabel.Name = "subtitleLabel"
    $subtitleLabel.Text = "XRK-Yunzai 机器人一键管理工具"
    $subtitleLabel.Font = Get-AdaptiveFont -baseSize 12
    $subtitleLabel.Location = New-Object System.Drawing.Point(30, 55)
    $subtitleLabel.Size = New-Object System.Drawing.Size(400, 25)
    $subtitleLabel.ForeColor = $global:colors.Secondary
    $titlePanel.Controls.Add($subtitleLabel)
    
    # 右上角功能按钮
    $proxyButton = New-ColoredButton "代理设置" ([System.Drawing.Point]::new(900, 20)) ([System.Drawing.Size]::new(100, 35)) $global:colors.Purple
    $proxyButton.Add_Click({ Show-ProxyDialog })
    $titlePanel.Controls.Add($proxyButton)
    
    $updateButton = New-ColoredButton "检查更新" ([System.Drawing.Point]::new(1020, 20)) ([System.Drawing.Size]::new(100, 35)) $global:colors.Warning
    $updateButton.Add_Click({
        if (Check-ForUpdates) {
            Perform-Update
        }
    })
    $titlePanel.Controls.Add($updateButton)
    
    $pathButton = New-ColoredButton "更改路径" ([System.Drawing.Point]::new(900, 60)) ([System.Drawing.Size]::new(100, 35)) $global:colors.Dark
    $pathButton.Add_Click({
        if (Get-InstallPath) {
            $envResult = Test-Environment
            $global:envStatusTextBox.Text = $envResult.StatusText
            $global:envStatusTextBox.SelectionLength = 0
        }
    })
    $titlePanel.Controls.Add($pathButton)
    
    $refreshButton = New-ColoredButton "刷新状态" ([System.Drawing.Point]::new(1020, 60)) ([System.Drawing.Size]::new(100, 35)) $global:colors.Success
    $refreshButton.Add_Click({
        Update-Status "正在刷新环境状态..." $global:colors.Primary
        $envResult = Test-Environment
        $global:envStatusTextBox.Text = $envResult.StatusText
        $global:envStatusTextBox.SelectionLength = 0
        Update-Status "环境状态已刷新" $global:colors.Success
        Write-ActionLog "环境刷新" "成功" "环境状态已更新"
    })
    $titlePanel.Controls.Add($refreshButton)
    
    # 路径信息标签
    $pathLabel = New-Object System.Windows.Forms.Label
    $pathLabel.Text = "当前路径: $global:yunzaiDir"
    $pathLabel.Location = New-Object System.Drawing.Point(30, 110)
    $pathLabel.Size = New-Object System.Drawing.Size(1120, 20)
    $pathLabel.Font = Get-AdaptiveFont -baseSize 9
    $pathLabel.ForeColor = $global:colors.Dark
    $pathLabel.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                        [System.Windows.Forms.AnchorStyles]::Left -bor 
                        [System.Windows.Forms.AnchorStyles]::Right
    $form.Controls.Add($pathLabel)
    
    # 主内容区域
    $contentPanel = New-Object System.Windows.Forms.Panel
    $contentPanel.Location = New-Object System.Drawing.Point(20, 140)
    $contentPanel.Size = New-Object System.Drawing.Size(1144, 590)
    $contentPanel.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                           [System.Windows.Forms.AnchorStyles]::Bottom -bor 
                           [System.Windows.Forms.AnchorStyles]::Left -bor 
                           [System.Windows.Forms.AnchorStyles]::Right
    $form.Controls.Add($contentPanel)
    
    # 环境状态组
    $envGroup = New-ModernGroupBox "环境状态" ([System.Drawing.Point]::new(0, 0)) ([System.Drawing.Size]::new(270, 280))
    $contentPanel.Controls.Add($envGroup)
    
    $global:envStatusTextBox = New-ScrollableTextBox ([System.Drawing.Point]::new(15, 30)) ([System.Drawing.Size]::new(240, 230))
    $envGroup.Controls.Add($global:envStatusTextBox)
    
    # 环境安装组
    $installGroup = New-ModernGroupBox "环境安装" ([System.Drawing.Point]::new(280, 0)) ([System.Drawing.Size]::new(270, 280))
    $contentPanel.Controls.Add($installGroup)
    
    $nodeButton = New-ModernButton "安装 Node.js" ([System.Drawing.Point]::new(15, 30)) ([System.Drawing.Size]::new(240, 35))
    $nodeButton.Add_Click({ Install-NodeJS })
    $installGroup.Controls.Add($nodeButton)
    
    $pnpmButton = New-ModernButton "安装 pnpm" ([System.Drawing.Point]::new(15, 75)) ([System.Drawing.Size]::new(240, 35))
    $pnpmButton.Add_Click({ Install-Pnpm })
    $installGroup.Controls.Add($pnpmButton)
    
    $gitButton = New-ModernButton "安装 Git" ([System.Drawing.Point]::new(15, 120)) ([System.Drawing.Size]::new(240, 35))
    $gitButton.Add_Click({ Install-Git })
    $installGroup.Controls.Add($gitButton)
    
    $redisButton = New-ModernButton "安装 Redis" ([System.Drawing.Point]::new(15, 165)) ([System.Drawing.Size]::new(240, 35))
    $redisButton.Add_Click({ Install-Redis })
    $installGroup.Controls.Add($redisButton)
    
    $ffmpegButton = New-ModernButton "安装 FFmpeg" ([System.Drawing.Point]::new(15, 210)) ([System.Drawing.Size]::new(240, 35))
    $ffmpegButton.Add_Click({ Install-FFmpeg })
    $installGroup.Controls.Add($ffmpegButton)
    
    # 项目操作组
    $projectGroup = New-ModernGroupBox "项目操作" ([System.Drawing.Point]::new(560, 0)) ([System.Drawing.Size]::new(270, 280))
    $contentPanel.Controls.Add($projectGroup)
    
    $cloneButton = New-ColoredButton "克隆 XRK-Yunzai" ([System.Drawing.Point]::new(15, 30)) ([System.Drawing.Size]::new(240, 40)) $global:colors.Primary
    $cloneButton.Add_Click({ Clone-XRKYunzai })
    $projectGroup.Controls.Add($cloneButton)
    
    $openProjectButton = New-ColoredButton "打开项目目录" ([System.Drawing.Point]::new(15, 80)) ([System.Drawing.Size]::new(240, 35)) $global:colors.Secondary
    $openProjectButton.Add_Click({
        if (Test-Path $global:projectPath) {
            Start-Process "explorer.exe" -ArgumentList $global:projectPath
            Write-ActionLog "打开目录" "成功" "已打开项目目录"
        } else {
            [System.Windows.Forms.MessageBox]::Show(
                "项目目录不存在", 
                "目录不存在", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Warning
            )
        }
    })
    $projectGroup.Controls.Add($openProjectButton)
    
    $startButton = New-ColoredButton "启动 XRK-Yunzai" ([System.Drawing.Point]::new(15, 125)) ([System.Drawing.Size]::new(240, 40)) $global:colors.Success
    $startButton.Add_Click({ Start-XRKYunzai })
    $projectGroup.Controls.Add($startButton)
    
    $napCatInstallButton = New-ColoredButton "下载 NapCatQQ" ([System.Drawing.Point]::new(15, 175)) ([System.Drawing.Size]::new(115, 35)) $global:colors.Purple
    $napCatInstallButton.Add_Click({ Install-NapCatQQ })
    $projectGroup.Controls.Add($napCatInstallButton)
    
    $napCatStartButton = New-ColoredButton "启动 NapCat" ([System.Drawing.Point]::new(140, 175)) ([System.Drawing.Size]::new(115, 35)) $global:colors.Warning
    $napCatStartButton.Add_Click({ Start-NapCatQQ })
    $projectGroup.Controls.Add($napCatStartButton)
    
    $openWorkspaceButton = New-ColoredButton "工作空间目录" ([System.Drawing.Point]::new(15, 220)) ([System.Drawing.Size]::new(240, 35)) $global:colors.Dark
    $openWorkspaceButton.Add_Click({
        if (Test-Path $global:workspacePath) {
            Start-Process "explorer.exe" -ArgumentList $global:workspacePath
            Write-ActionLog "打开目录" "成功" "已打开工作空间目录"
        } else {
            [System.Windows.Forms.MessageBox]::Show(
                "工作空间目录不存在", 
                "目录不存在", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Warning
            )
        }
    })
    $projectGroup.Controls.Add($openWorkspaceButton)
    
    # 快速操作组
    $quickGroup = New-ModernGroupBox "快速操作" ([System.Drawing.Point]::new(840, 0)) ([System.Drawing.Size]::new(304, 280))
    $contentPanel.Controls.Add($quickGroup)
    
    $quickLabel = New-Object System.Windows.Forms.Label
    $quickLabel.Text = @"
一键操作说明：
• 全新安装：按顺序安装所有环境
• 一键启动：启动Redis+NapCat+Yunzai
• 查看日志：查看安装和操作日志

提示：
• 建议先执行全新安装
• 确保有足够的磁盘空间（至少2GB）
• 安装过程需要网络连接
"@
    $quickLabel.Location = New-Object System.Drawing.Point(15, 30)
    $quickLabel.Size = New-Object System.Drawing.Size(274, 120)
    $quickLabel.Font = Get-AdaptiveFont -baseSize 9
    $quickGroup.Controls.Add($quickLabel)
    
    $installAllButton = New-ColoredButton "全新安装（推荐）" ([System.Drawing.Point]::new(15, 160)) ([System.Drawing.Size]::new(274, 40)) $global:colors.Primary
    $installAllButton.Add_Click({
        $result = [System.Windows.Forms.MessageBox]::Show(
            "将按顺序安装所有必需环境，是否继续？", 
            "全新安装", 
            [System.Windows.Forms.MessageBoxButtons]::YesNo, 
            [System.Windows.Forms.MessageBoxIcon]::Question
        )
        if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
            Write-ActionLog "全新安装" "开始" "开始批量安装所有环境"
            $steps = @(
                @{Name="Node.js"; Action={Install-NodeJS}},
                @{Name="pnpm"; Action={Install-Pnpm}},
                @{Name="Git"; Action={Install-Git}},
                @{Name="Redis"; Action={Install-Redis}},
                @{Name="FFmpeg"; Action={Install-FFmpeg}},
                @{Name="NapCatQQ"; Action={Install-NapCatQQ}}
            )
            $success = $true
            foreach ($step in $steps) {
                Update-Status "正在安装 $($step.Name)..." $global:colors.Primary
                if (-not (& $step.Action)) {
                    $success = $false
                    Update-Status "$($step.Name) 安装失败" $global:colors.Danger
                    Write-ActionLog "全新安装" "中断" "$($step.Name) 安装失败"
                    break
                }
            }
            if ($success) {
                Update-Status "全新安装完成！" $global:colors.Success
                Write-ActionLog "全新安装" "成功" "所有环境安装完成"
                [System.Windows.Forms.MessageBox]::Show(
                    "所有环境安装完成！", 
                    "安装成功", 
                    [System.Windows.Forms.MessageBoxButtons]::OK, 
                    [System.Windows.Forms.MessageBoxIcon]::Information
                )
            }
            $envResult = Test-Environment
            $global:envStatusTextBox.Text = $envResult.StatusText
            $global:envStatusTextBox.SelectionLength = 0
        }
    })
    $quickGroup.Controls.Add($installAllButton)
    
    $startAllButton = New-ColoredButton "一键启动所有" ([System.Drawing.Point]::new(15, 210)) ([System.Drawing.Size]::new(130, 35)) $global:colors.Success
    $startAllButton.Add_Click({
        Write-ActionLog "一键启动" "开始" "启动所有服务"
        
        # 启动Redis服务
        $redisRunning = (Get-Service -Name "Redis" -ErrorAction SilentlyContinue).Status -eq "Running"
        if (-not $redisRunning) {
            try {
                Start-Service -Name "Redis"
                Update-Status "Redis服务已启动" $global:colors.Success
                Write-ActionLog "启动Redis" "成功" "Redis服务已启动"
            } catch {
                Update-Status "Redis启动失败" $global:colors.Danger
                Write-ActionLog "启动Redis" "失败" $_.Exception.Message
            }
        }
        Start-Sleep -Seconds 1
        
        # 启动NapCat
        Start-NapCatQQ
        Start-Sleep -Seconds 2
        
        # 启动Yunzai
        Start-XRKYunzai
        Write-ActionLog "一键启动" "完成" "所有服务启动完成"
    })
    $quickGroup.Controls.Add($startAllButton)
    
    $viewLogButton = New-ColoredButton "查看日志" ([System.Drawing.Point]::new(155, 210)) ([System.Drawing.Size]::new(134, 35)) $global:colors.Secondary
    $viewLogButton.Add_Click({
        if (Test-Path $global:logPath) {
            Start-Process "notepad.exe" -ArgumentList $global:logPath
            Write-ActionLog "查看日志" "成功" "已打开日志文件"
        } else {
            [System.Windows.Forms.MessageBox]::Show(
                "日志文件不存在", 
                "无日志", 
                [System.Windows.Forms.MessageBoxButtons]::OK, 
                [System.Windows.Forms.MessageBoxIcon]::Information
            )
        }
    })
    $quickGroup.Controls.Add($viewLogButton)
    
    # 日志输出组
    $logGroup = New-ModernGroupBox "操作日志" ([System.Drawing.Point]::new(0, 290)) ([System.Drawing.Size]::new(1144, 300))
    $contentPanel.Controls.Add($logGroup)
    
    $logTextBox = New-ScrollableTextBox ([System.Drawing.Point]::new(15, 30)) ([System.Drawing.Size]::new(1114, 250))
    $logTextBox.Font = New-Object System.Drawing.Font("Consolas", 9)
    $logGroup.Controls.Add($logTextBox)
    
    # 状态栏
    $statusBar = New-Object System.Windows.Forms.StatusStrip
    $statusBar.BackColor = $global:colors.Dark
    $statusBar.SizingGrip = $false
    $script:statusLabel = New-Object System.Windows.Forms.ToolStripStatusLabel
    $script:statusLabel.Text = "就绪"
    $script:statusLabel.ForeColor = $global:colors.White
    $script:statusLabel.Spring = $true
    $script:statusLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleLeft
    $statusBar.Items.Add($script:statusLabel) | Out-Null
    $form.Controls.Add($statusBar)
    
    # 重定向控制台输出到日志文本框
    $originalOut = [Console]::Out
    $writer = New-Object System.IO.StringWriter
        # 重定向控制台输出到日志文本框（接续）
    [Console]::SetOut($writer)
    
    $timer = New-Object System.Windows.Forms.Timer
    $timer.Interval = 100
    $timer.Add_Tick({
        $output = $writer.GetStringBuilder().ToString()
        if ($output) {
            $writer.GetStringBuilder().Clear() | Out-Null
            $logTextBox.AppendText($output)
            $logTextBox.SelectionStart = $logTextBox.Text.Length
            $logTextBox.ScrollToCaret()
        }
    })
    $timer.Start()
    
    # 窗口大小改变事件
    $form.Add_SizeChanged({
        Update-ScaleFactor -form $form
        Update-AllControlsFonts -container $form
    })
    
    # 窗口关闭事件
    $form.Add_FormClosing({
        $timer.Stop()
        [Console]::SetOut($originalOut)
        Save-Config
        Write-ActionLog "程序退出" "正常" "用户关闭程序"
    })
    
    # 初始化环境状态
    Update-Status "正在检测环境..." $global:colors.Primary
    $envResult = Test-Environment
    $global:envStatusTextBox.Text = $envResult.StatusText
    $global:envStatusTextBox.SelectionLength = 0
    Update-Status "环境检测完成" $global:colors.Success
    
    # 显示窗口
    [System.Windows.Forms.Application]::Run($form)
}

function Update-ScaleFactor {
    param([System.Windows.Forms.Form]$form)
    $baseWidth = 1200
    $currentWidth = $form.Width
    $global:scaleFactor = [Math]::Max(0.8, [Math]::Min(2.0, $currentWidth / $baseWidth))
}

function Update-AllControlsFonts {
    param([System.Windows.Forms.Control]$container)
    try {
        foreach ($control in $container.Controls) {
            if ($control -is [System.Windows.Forms.Button]) {
                $control.Font = Get-AdaptiveFont -baseSize 9 -style Bold
            } elseif ($control -is [System.Windows.Forms.Label]) {
                if ($control.Name -eq "titleLabel") {
                    $control.Font = Get-AdaptiveFont -baseSize 20 -style Bold
                } elseif ($control.Name -eq "subtitleLabel") {
                    $control.Font = Get-AdaptiveFont -baseSize 12
                } else {
                    $control.Font = Get-AdaptiveFont -baseSize 9
                }
            } elseif ($control -is [System.Windows.Forms.GroupBox]) {
                $control.Font = Get-AdaptiveFont -baseSize 10 -style Bold
            } elseif ($control -is [System.Windows.Forms.TextBox]) {
                $control.Font = Get-AdaptiveFont -baseSize 9
            }
            if ($control.HasChildren) { 
                Update-AllControlsFonts $control 
            }
        }
    } catch {}
}
#endregion

#region 主程序入口
try {
    Write-Host "=====================================`r`n" -ForegroundColor Cyan
    Write-Host "   葵崽专属管理器 v$global:appVersion   `r`n" -ForegroundColor Cyan
    Write-Host "=====================================`r`n" -ForegroundColor Cyan
    Write-Host "作者: 向日葵" -ForegroundColor Yellow
    Write-Host "功能: XRK-Yunzai 机器人一键管理工具" -ForegroundColor Gray
    Write-Host "`r`n正在初始化..." -ForegroundColor Gray
    
    # 加载配置
    Write-Host "加载配置文件..." -ForegroundColor Gray
    Load-Config
    
    # 初始化Git Bash路径
    Write-Host "检测Git Bash路径..." -ForegroundColor Gray
    Initialize-GitBashPath
    
    # 检查是否需要显示路径选择对话框
    if (-not $global:skipPathDialog -or -not $global:basePath -or -not (Test-Path $global:yunzaiDir)) {
        Write-Host "需要设置安装路径..." -ForegroundColor Yellow
        if (-not (Get-InstallPath)) {
            Write-Host "`r`n用户取消了路径选择，程序退出" -ForegroundColor Yellow
            Start-Sleep -Seconds 2
            exit
        }
    } else {
        # 使用保存的路径初始化
        $yunzaiDirName = Split-Path $global:yunzaiDir -Leaf
        Initialize-Paths -baseInstallPath $global:basePath -yunzaiDirName $yunzaiDirName
        Write-Host "使用保存的路径: $global:yunzaiDir" -ForegroundColor Green
    }
    
    Write-Host "`r`n初始化完成，正在启动主界面..." -ForegroundColor Green
    Start-Sleep -Seconds 1
    
    # 启动主窗口
    Show-MainWindow
    
} catch {
    Write-Host "`r`n程序发生严重错误:" -ForegroundColor Red
    Write-Host "错误信息: $($_.Exception.Message)" -ForegroundColor Red
    Write-Host "`r`n错误堆栈:" -ForegroundColor DarkGray
    Write-Host $_.ScriptStackTrace -ForegroundColor DarkGray
    
    [System.Windows.Forms.MessageBox]::Show(
        "程序发生严重错误：`n`n$($_.Exception.Message)`n`n请将错误信息截图发送给开发者", 
        "程序错误", 
        [System.Windows.Forms.MessageBoxButtons]::OK, 
        [System.Windows.Forms.MessageBoxIcon]::Error
    )
} finally {
    # 确保资源释放
    if ($writer) { $writer.Dispose() }
    if ($timer) { $timer.Dispose() }
}
#endregion

# 程序结束
Write-Host "`r`n程序已退出" -ForegroundColor Gray